package photogcalc.calc;

/** Calculates the depth of field and the hyperfocal distance.
 *  All calculations are done using the metric system and millimetres.
 *
 *  @see http://www.tawbaware.com/maxlyons/calc.htm
 *
 *
 *  @version 2007-12-08
 *  @author Antti Okkonen
*/
public class DepthOfField {
    protected double CoC;
    protected double hyperfocal, near, far;

    /** Default constructor. Default CoC is for 35mm film frame. */
    public DepthOfField() {
        this(0.03); // 35mm film
    }

    /** Default constructor.
     *
     * @param coc circle of confusion
     */
    public DepthOfField(double coc) {
        CoC = coc;
    }

    private double hyperfocalDistance(double f, double N, double c) {
        return ((f * f) / (N * c)) + f;
    }

    private double nearDistance(double s, double H, double f) {
        return (H * s) / (H + (s - f));
        //return (s*(H-f))/(H+s-f*f);
    }

    private double farDistance(double s, double H, double f) {
        return (H * s) / (H - (s - f));
        //return (s*(H-f))/(H-s);
    }

    /** @return hyperfocal distance */
    public double getHyperfocalDistance() {
        return hyperfocal;
    }

    /** @return near distance */
    public double getNearDistance() {
        return near;
    }

    /** @return far distance */
    public double getFarDistance() {
        return far;
    }

    /** Calculates hyperfocal near, far and hyperfocal distances.
    @param f focal length
    @param N aperture
    @param s distance
     */
    public void calculate(double f, double N, double s) {
        double H = hyperfocal = hyperfocalDistance(f, N, CoC);
        near = nearDistance(s, H, f);
        far = farDistance(s, H, f);
    }
}
